package org.me.marble;

/**
*
* @author tungi
*/

public class Vector {
    private float x,y,z;

    ////////////////////////////CONSTRUCTORS////////////////////////////////////
    public Vector(){
        x=y=z=0;
    }

    public Vector(float x,float y,float z){
        this.x=x;
        this.y=y;
        this.z=z;
    }

    public Vector(double x,double y,double z){
        this.x=(float)x;
        this.y=(float)y;
        this.z=(float)z;
    }

    public Vector(Vector _vector){
        this.x=_vector.x;
        this.y=_vector.y;
        this.z=_vector.z;
    }

    ///////////////////////////////SET METHODS//////////////////////////////////
    public void set(float _x,float _y,float _z){
        x=_x;
        y=_y;
        z=_z;
    }

    public void set(double _x,double _y,double _z){
        x=(float)_x;
        y=(float)_y;
        z=(float)_z;
    }

    public void setX(float _x){
        this.x=_x;
    }

    public void setY(float _y){
        this.y=_y;
    }

    public void setZ(float _z){
        this.z=_z;
    }

    public float[] toArray(){
        return new float[]{x,y,z};
    }

    ///////////////////////////////GET METHODS//////////////////////////////////
    public float getX(){
        return this.x;
    }

    public float getY(){
        return this.y;
    }

    public float getZ(){
        return this.z;
    }

    public Vector getNomalizedVector(){
        Vector ret=new Vector(x,y,z);
        ret.Normalize();
        return ret;
    }

    ////////////////////////////////FUNCTIONS///////////////////////////////////
    public void Normalize(){
        float l=Length();
        x/=l;y/=l;z/=l;
        float m=getMax();
        x/=m;y/=m;z/=m;
    }

    public float getMax(){
        float max=Math.abs(x)>Math.abs(y)?Math.abs(x):Math.abs(y);
        max=max>Math.abs(z)?max:Math.abs(z);
        return max;
    }

    public float Length(){
        return (float)Math.sqrt(x*x+y*y+z*z);
    }

    ////////////////////////MATHEMATIC FUNCTIONS////////////////////////////////
    public void  Plus(Vector v){
        x+=v.getX();
        y+=v.getY();
        z+=v.getZ();
    }

    public void  Minus(Vector v){
        x-=v.getX();
        y-=v.getY();
        z-=v.getZ();
    }

    public void Multiplication(double m){
        x*=m;y*=m;z*=m;
    }

    public void Product(Vector v){
        x*=v.getX();
        y*=v.getY();
        z*=v.getZ();
    }

    public void crossProduct(Vector v){
        float _x=y*v.getZ()-z*v.getY();
        float _y=z*v.getX()-x*v.getZ();
        float _z=x*v.getY()-y*v.getX();
        x=_x;y=_y;z=_z;
    }
    ////////////////////////////STATIC FUNCTIONS////////////////////////////////

    public static Vector Plus(Vector v1,Vector v2){
        return new Vector(v1.getX()+v2.getX(),v1.getY()+v2.getY(),v1.getZ()+v2.getZ());
    }

    public static Vector Minus(Vector v1,Vector v2){
        return new Vector(v1.getX()-v2.getX(),v1.getY()-v2.getY(),v1.getZ()-v2.getZ());
    }

    public static Vector Multiplication(Vector v,double m){
        return new Vector(v.getX()*m,v.getY()*m,v.getZ()*m);
    }    

    public static Vector Product(Vector v1,Vector v2){
        return new Vector(v1.getX()*v2.getX(),v1.getY()*v2.getY(),v1.getZ()*v2.getZ());
    }

    public static Vector crossProduct(Vector v1,Vector v2){
        float _x=v1.getY()*v2.getZ()-v1.getZ()*v2.getY();
        float _y=v1.getZ()*v2.getX()-v1.getX()*v2.getZ();
        float _z=v1.getX()*v2.getY()-v1.getY()*v2.getX();
        return new Vector(_x,_y,_z);
    }

    public static float dotProduct(Vector v1,Vector v2){
        return v1.getX()*v2.getX()+v1.getY()*v2.getY()+v1.getZ()*v2.getZ();
    }

    public static boolean Equal(Vector a,Vector b){
        if(a.getX()==b.getX() && a.getY()==b.getY() && a.getZ()==b.getZ())
            return true;
        else return false;
    }
}
